import numpy as np
import csv
import random
from datetime import datetime
from time import strftime
from scipy.stats import scoreatpercentile
import math as math


def getCurTime():
    """
    get current time
    Return value of the date string format(%Y-%m-%d %H:%M:%S)
    """
    format='%Y-%m-%d %H:%M:%S'
    sdate = None
    cdate = datetime.now()
    try:
        sdate = cdate.strftime(format)
    except:
        raise ValueError
    return sdate

def build_data_list(inputCSV):
    sKey = []
    fn = inputCSV
    ra = csv.DictReader(file(fn), dialect="excel")
    
    for record in ra:
        #print record[ra.fieldnames[0]], type(record[ra.fieldnames[-1]])
        for item in ra.fieldnames:
            temp = float(record[item])
            sKey.append(temp)
    sKey = np.array(sKey)
    sKey.shape=(-1,len(ra.fieldnames))
    return sKey

def build_pvalue_list(inputCSV):
    sKey = []
    fn = inputCSV
    ra = csv.DictReader(file(fn), dialect="excel")
    
    for record in ra:
        temp = float(record[ra.fieldnames[-1]])
        sKey.append(temp)
    sKey = np.array(sKey)
    return sKey

def build_satscanresult_dbf(inputDBF):
    sKey = np.array([])
    fn = inputDBF
    db = dbf.Dbf(fn)
    for record in db:
        temp = float(record[db.fieldNames[2]])
        temp_id = int(float(record[db.fieldNames[0]]))
        sKey = np.append(sKey, temp_id)
        temp_id = int(float(record[db.fieldNames[1]]))
        sKey = np.append(sKey, temp_id)
        sKey = np.append(sKey, temp)
    sKey.shape = (-1, 3)
    return sKey

def build_satscanresult_pvalue(arrayLen, inputDBF):
    # build a list of pvalue, if not found in DBF, set as 1
    tPvalue = np.ones(arrayLen)
    tempResult = build_satscanresult_dbf(inputDBF)
    #i = 0
    for item in tempResult:
        tPvalue[int(item[0])] = item[2]
    return tPvalue

def cal_poisson_likelihood_ratio(iObZ, iObT, iPopZ, iPopT):
    # iObZ: the observed number in the certain Zone, e.g. the number of cancer cases in a region
    # iObT: the total observed number, e.g. the total number of cancer cases
    # iPopZ: the population in the certain Zone 
    # iPopT: the total population
    # return the natural logarithm of ratio
    temp_lambda = 0.0
    temp_z_p = (0.0 + iObZ)/iPopZ
    temp_out_p = (0.0 + iObT - iObZ)/(iPopT - iPopZ)
    temp_t_p = (0.0 + iObT)/iPopT
    #print temp_out_p
    #temp_lambda = iObZ * math.log(temp_z_p) + (iObT - iObZ)* math.log(temp_out_p) - iObT * math.log(temp_t_p)
    if temp_z_p > temp_out_p:
        temp_lambda = iObZ * math.log(temp_z_p) + (iObT - iObZ)* math.log(temp_out_p) - iObT * math.log(temp_t_p)

    return temp_lambda

def build_region_list(tPvalue):
    i = 0
    tempList = []
    for item in pvalue:
        if item == tPvalue:
            tempList.append(i)
        i += 1
    return tempList

def cal_region_attri(tList, ti):
    temp = [0.0, 0.0]
    for item in tList:
        temp[0] += dataMatrix[item, 1]
        temp[1] += dataMatrix[item, ti+2]
    return temp

def build_cluster_llr(tPvalue, repeat):
    ttLLR = []
    for p in tPvalue:
        list = build_region_list(p)
        #print list
        tAttri = cal_region_attri(list, repeat)
        #print tAttri[0], case, tAttri[1], pop
        tLLR = cal_poisson_likelihood_ratio(tAttri[1], case, tAttri[0], pop)
        ttLLR.append(tLLR)
    return ttLLR

def build_regionData_list(inputCSV):
    sKey = []
    fn = inputCSV
    ra = csv.DictReader(file(fn), dialect="excel")
    
    for record in ra:
        #print record[ra.fieldnames[0]], type(record[ra.fieldnames[-1]])
        #for item in ra.fieldnames:
        temp = int(float(record[ra.fieldnames[-1]]))
        sKey.append(temp)
    #sKey = np.array(sKey)
    #sKey.shape=(-1,len(ra.fieldnames))
    return sKey

def cal_region_llr(region_attri):
    ttLLR = []
    for item in region_attri:
        tLLR = cal_poisson_likelihood_ratio(item[0], case, item[1], pop)
        #print item[0], case, item[1], pop, tLLR 
        ttLLR.append(tLLR)
    return ttLLR
    

#--------------------------------------------------------------------------
#MAIN

if __name__ == "__main__":
    print "begin at " + getCurTime()
    unitCSV = 'C:/_DATA/CancerData/SatScan/mult6000/three16_modify/three16_format_modify.csv'
    dataMatrix = build_data_list(unitCSV)  # [id, pop, cancer1, cancer2, cancer3]
    #print dataMatrix
    #pop = sum(dataMatrix[:,1])
    pop = 29535210
    case = 6000
    result = []

    
    filePath = 'C:/_DATA/CancerData/SatScan/mult6000/three16_modify/LLR/'
    repeatTime = 1000
    for repeat in range(0, repeatTime):
        #case = sum(dataMatrix[:,repeat+2])

        pvalueCSV = filePath + 'LLR_EBS_high_' + str(repeat) + "_pvalue.csv"
        regionCSV = filePath + 'LLR_EBS_high_' + str(repeat) + ".csv"
        #regionList = build_region(regionCSV)
        regionList =  build_regionData_list(regionCSV)
        temp = np.unique(regionList)
        region_attri = np.zeros((len(temp), 2))
        
        k = 0
        for item in regionList:
            region_attri[int(item), 0] += dataMatrix[k,repeat+2]
            region_attri[int(item), 1] += dataMatrix[k,1]
            k += 1

        region_llr = cal_region_llr(region_attri)
        temp_region_llr = np.sort(region_llr)
        #print temp_region_llr, temp_region_llr[-3:]
        '''
        pvalue = build_pvalue_list(pvalueCSV)
        u_pvalue = np.unique(pvalue)

        #print u_pvalue, u_pvalue[:-1]
        if len(u_pvalue) > 0:
            t_pvalue = u_pvalue[:1]
            t = build_cluster_llr(t_pvalue, repeat)
            result.append(t[0])
        else:
            #t_pvalue = u_pvalue[:-1]
            result.append(0)
            print repeat
        
        #t = build_cluster_llr(t_pvalue, repeat)
        #print t, t[0]
        #for item in t:
            #result.append(item)
        '''
        result.append(temp_region_llr[-3:])
    result = np.array(result)
    print result, len(result), np.average(result)
    fileLoc = 'C:/4.csv'
    np.savetxt(fileLoc, result, delimiter=',', fmt = '%10.5f')
    print "end at " + getCurTime()
    print "========================================================================"  

           
